﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using GlobalHelper;
using IBDM2IBSInterface;

namespace Models
{
    public class TimeTableModel
    {
        private IList<TokenModel> _tokens = new List<TokenModel>();
        private IList<TurnModel> _turns = new List<TurnModel>();
        private ILine _lineBaseInfo;

        public ILine LineBaseInfo { get { return _lineBaseInfo; } }
        public IList<TokenModel> Tokens { get { return _tokens; } }
        public IList<TurnModel> Turns { get { return _turns; } }

        public int Id { get; set; }
        public string Name { get; set; }
        public int TurnAmount { get; set; }
        public int TokenAmount { get; set; }
        public bool Valid { get; set; }


        public TimeTableModel()
        {

        }

        public TimeTableModel(int turnAmount, int tokenAmount, ILine lineBaseInfo)
        {
            TurnAmount = turnAmount;
            TokenAmount = tokenAmount;
            Name = lineBaseInfo.Name;
            _lineBaseInfo = lineBaseInfo;
        }

        private TimeTableModel(int turnAmount, int tokenAmount)
        {
            TurnAmount = turnAmount;
            TokenAmount = tokenAmount;
        }

        private TimeTableModel(string name, int turnAmount, int tokenAmount, bool valid)
        {
            Name = name;
            TurnAmount = turnAmount;
            TokenAmount = tokenAmount;
            Valid = valid;
        }

        /// <summary>
        /// 初始化时刻表
        /// </summary>
        public void Init()
        {
            #region Init

            var station = LineBaseInfo.StartStation;

            int balance = 0;

            //init tokens
            if (_tokens.Count < TokenAmount)
            {
                balance = TokenAmount - _tokens.Count;

                for (int i = 0; i < balance; i++)
                {
                    var part1 = new PartModel();
                    var token = new TokenModel();

                    part1.FirstTurn = 0;//startTurnNumber;//对导入降低要求,在自动生成时需用到 to do by feilx
                    part1.TokenPosition = i;
                    part1.OwnTokenModel = token;

                    token.Id = i;
                    token.OwnTimeSheet = this;
                    token.FirstPart = part1;

                    this._tokens.Add(token);
                }
            }

            //init turns
            if (_turns.Count < TurnAmount)
            {
                balance = TurnAmount - _turns.Count;

                for (int i = 0; i < balance; i++)
                {

                    #region CreateTurn

                    var turn = new TurnModel();
                    if (i % 2 == 1)
                    {
                        turn = new TurnModel(i, station, station.ToStation, DirectionState.UpLink);
                    }
                    else
                    {
                        turn = new TurnModel(i, station, station.ToStation, DirectionState.DownLink);
                    }
                    station = station.ToStation;

                    #endregion
                    this._turns.Add(turn);
                }
            }

            #endregion
        }

        public DataTable ToDataTable()
        {
            if (Tokens.Count == 0)
            {
                return null;
            }

            var result = new DataTable();

            #region Init

            //init dtatSource
            for (int i = 0; i < TurnAmount; i++)
            {
                DataColumn column;
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");

                //if (i % 2 == 0)
                //    column.ColumnName = startStationName + i;
                //else
                //    column.ColumnName = endStationName + i;

                result.Columns.Add(column);
            }

            for (int i = 0; i < TokenAmount; i++)
            {
                result.Rows.Add(result.NewRow());
            }

            #endregion

            foreach (TokenModel token in Tokens)
            {
                //first part
                if (token.FirstPart != null && token.FirstPart.Count > 0)
                {
                    int row = token.FirstPart.TokenPosition;
                    int col = token.FirstPart.FirstTurn;

                    for (int i = 0; i < token.FirstPart.Dapartures.Count; i++)
                    {
                        result.Rows[row][col + i] = token.FirstPart.Dapartures[i].Time;
                    }

                    //foreach (DepartureModel daparture in token.FirstPart.Dapartures)
                    //{
                    //    result.Rows[row][col] = daparture.Time;
                    //}
                }
                //second part
                if (token.SecondPart != null && token.SecondPart.Count > 0)
                {
                    int row = token.SecondPart.TokenPosition;
                    int col = token.SecondPart.FirstTurn;

                    for (int i = 0; i < token.SecondPart.Dapartures.Count; i++)
                    {
                        result.Rows[row][col + i] = token.SecondPart.Dapartures[i].Time;
                    }

                    //foreach (DepartureModel daparture in token.SecondPart.Dapartures)
                    //{
                    //    result.Rows[row][col] = daparture.Time;
                    //}
                }
            }

            return result;
        }

        /// <summary>
        /// 返回 按指定 周转 序列 的 所有发车时间信息
        /// </summary>
        /// <param name="turnNumber"></param>
        /// <returns>Part序 内容为发车时间</returns>
        public IList<int> GetTurnDeparturesInfo(int turnNumber)
        {
            IList<int> result = new List<int>();

            //var listOrder = GetTurnOrder(turnNumber);

            //foreach (int i in listOrder)
            //{
            //    result.Add(Turns[turnNumber].Dapartures[i].Time);
            //}

            result = _turns[turnNumber].ToList();

            return result;
        }

        #region FirstTurnAndLastTurn

        /// <summary>
        /// 当前已生成数据的第一个周转
        /// </summary>
        public TurnModel CurrFirstTurn()
        {
            //返回 首个 Dep集合数量非0的turn
            foreach (TurnModel turn in Turns)
            {
                if (turn.Dapartures.Count != 0)
                {
                    return turn;
                }
            }
            return null;
        }

        public IList<int> GetCurrFirstTurnOrder()
        {
            IList<int> result = new List<int>();

            foreach (var dep in CurrFirstTurn().Dapartures)
            {
                result.Add(dep.OwnPart.TokenPosition);
            }

            return result;
        }

        /// <summary>
        /// 当前已生成数据的最后一个周转
        /// </summary>
        public TurnModel CurrLastTurn()
        {
            for (int i = Turns.Count - 1; i >= 0; i--)
            {
                if (Turns[i].Dapartures.Count != 0)
                {
                    return Turns[i];
                }
            }
            return null;
        }

        public IList<int> GetCurrLastTurnOrder()
        {
            IList<int> result = new List<int>();

            foreach (var dep in CurrLastTurn().Dapartures)
            {
                result.Add(dep.OwnPart.TokenPosition);
            }

            return result;
        }

        #endregion

        #region 删除空的路牌

        public void RemoveEmptyNode()
        {
            IList<TokenModel> removeAbleList = new List<TokenModel>();

            foreach (TokenModel token in _tokens)
            {
                if (string.IsNullOrEmpty(token.Name))
                {
                    removeAbleList.Add(token);
                }
            }

            foreach (TokenModel node in removeAbleList)
            {
                var list = RemoveNode(_tokens, node);
                _tokens = list;
            }   
        }
        #endregion

        internal IList<TokenModel> RemoveNode(IList<TokenModel> list, TokenModel node)
        {
            IList<TokenModel> result = new List<TokenModel>();

            result = list;

            result.Remove(node);

            return result;
        }
    }
}
